package cn.iocoder.yudao.module.wine.service.userfans;

import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.wine.controller.app.userfans.enums.UserFansSubscribeEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

import cn.iocoder.yudao.module.wine.controller.app.userfans.vo.*;
import cn.iocoder.yudao.module.wine.dal.dataobject.userfans.UserFansDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.wine.dal.mysql.userfans.UserFansMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.wine.enums.ErrorCodeConstants.*;

/**
 * 用户粉丝信息 Service 实现类
 *
 * @author 管理员
 */
@Service
@Validated
public class UserFansServiceImpl implements UserFansService {

    @Resource
    private UserFansMapper userFansMapper;

    @Resource
    private MemberUserApi memberUserApi;

    @Override
    public Long createUserFans(AppUserFansSaveReqVO createReqVO) {
        // 插入
        UserFansDO userFans = BeanUtils.toBean(createReqVO, UserFansDO.class);
        userFansMapper.insert(userFans);
        // 返回
        return userFans.getId();
    }

    @Override
    public void updateUserFans(AppUserFansSaveReqVO updateReqVO) {
        // 校验存在
        validateUserFansExists(updateReqVO.getId());
        // 更新
        UserFansDO updateObj = BeanUtils.toBean(updateReqVO, UserFansDO.class);
        userFansMapper.updateById(updateObj);
    }

    @Override
    public void deleteUserFans(Long id) {
        // 校验存在
        validateUserFansExists(id);
        // 删除
        userFansMapper.deleteById(id);
    }

    private void validateUserFansExists(Long id) {
        if (userFansMapper.selectById(id) == null) {
            throw exception(INFO_NOT_EXISTS);
        }
    }

    @Override
    public UserFansDO getUserFans(Long id) {
        return userFansMapper.selectById(id);
    }

    @Override
    public PageResult<UserFansDO> getUserFansPage(AppUserFansPageReqVO pageReqVO) {
        return userFansMapper.selectPage(pageReqVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer subscribe(AppUserFansSaveReqVO createReqVO) {
        Long userId = createReqVO.getUserId();
        validateMemberUserExists(userId);
        Long fansId = SecurityFrameworkUtils.getLoginUserId();
        UserFansDO userFansDO = userFansMapper.selectOne(new LambdaQueryWrapper<UserFansDO>()
                .eq(UserFansDO::getUserId, userId)
                .eq(UserFansDO::getFansId, fansId));

        if (userFansDO == null) {
            //首次关注
            UserFansDO data = BeanUtils.toBean(createReqVO, UserFansDO.class);
            data.setFansId(fansId);
            data.setSubscribeStatus(UserFansSubscribeEnum.SUBSCRIBE.getStatus());
            data.setSubscribeTime(LocalDateTime.now());
            return userFansMapper.insert(data);
        }

        if (UserFansSubscribeEnum.SUBSCRIBE.getStatus().equals(userFansDO.getSubscribeStatus())) {
            //取消关注
            userFansDO.setUnsubscribeTime(LocalDateTime.now());
            userFansDO.setSubscribeStatus(UserFansSubscribeEnum.UNFOLLOW.getStatus());
        }else {
            userFansDO.setSubscribeStatus(UserFansSubscribeEnum.SUBSCRIBE.getStatus());
            userFansDO.setUnsubscribeTime(null);
        }
        return userFansMapper.updateById(userFansDO);
    }

    @Override
    public List<AppUserFansListVO> getFansList(AppUserFansReqVO reqVO) {
        if (reqVO.getUserId() != null) {
            return userFansMapper.getFansList(reqVO.getUserId());
        }
        return userFansMapper.getFansList(SecurityFrameworkUtils.getLoginUserId());
    }

    @Override
    public List<AppUserFansListVO> getSubscribeList(AppUserFansReqVO reqVO) {
        if (reqVO.getUserId() != null) {
            return userFansMapper.getSubscribeList(reqVO.getUserId());
        }
        return userFansMapper.getSubscribeList(SecurityFrameworkUtils.getLoginUserId());

    }

    @Override
    public Long getFansNum(Long id) {
        return userFansMapper.selectCount(new LambdaQueryWrapperX<UserFansDO>()
                .eq(UserFansDO::getUserId, id)
                .eq(UserFansDO::getSubscribeStatus, UserFansSubscribeEnum.SUBSCRIBE.getStatus())
        );
    }

    @Override
    public Long getSubscribeNum(Long id) {
        return userFansMapper.selectCount(new LambdaQueryWrapperX<UserFansDO>()
                .eq(UserFansDO::getFansId, id)
                .eq(UserFansDO::getSubscribeStatus, UserFansSubscribeEnum.SUBSCRIBE.getStatus())
        );

    }

    private void validateMemberUserExists(Long id) {
        if (memberUserApi.getUser(id) == null) {
            throw exception(USER_NOT_EXISTS);
        }
    }

}
